package kassiopeia.agent.io;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.log4j.Logger;
import com.google.common.base.Preconditions;
import kassiopeia.commons.io.Message;

public class ReceiversRegistry {

    private static final Logger logger = Logger.getLogger(ReceiversRegistry.class);

    private String thisAgentId;
    private List<MessageReceiver> messageReceivers;

    public ReceiversRegistry() {}

    public ReceiversRegistry(String agentId, List<MessageReceiver> messageReceivers) {
        Preconditions.checkNotNull(messageReceivers);
        Preconditions.checkNotNull(agentId);

        this.thisAgentId = agentId;
        this.messageReceivers = messageReceivers;
    }

    public ReceiversRegistry(List<MessageReceiver> messageReceivers) {
        this(null, messageReceivers);
    }

    public synchronized List<MessageReceiver> getAll() {
        List<MessageReceiver> copied = new ArrayList<MessageReceiver>();
        Collections.copy(copied, messageReceivers);
        return copied;
    }

    public synchronized void notifyReceivers(Message message) {
        String agentId = message.getSourceId();
        if(thisAgentId.equals(agentId)) {
            logger.debug("Ignoring message send by myself");
            return;
        }

        int receiversCount = 0;
        for(MessageReceiver mr : messageReceivers) {
            for(Class<? extends Message> c : mr.acceptedMessages()) {
                if(c.isInstance(message)) {
                    mr.onMessage(message);
                    receiversCount++;
                }
            }
        }

        logger.debug(receiversCount + " receiver(s) were notified about incoming message");
    }

    public String getThisAgentId() {
        return thisAgentId;
    }

    public void setThisAgentId(String thisAgentId) {
        this.thisAgentId = thisAgentId;
    }

    public List<MessageReceiver> getMessageReceivers() {
        return messageReceivers;
    }

    public void setMessageReceivers(List<MessageReceiver> messageReceivers) {
        this.messageReceivers = messageReceivers;
    }
}
